/*
 * This file is Copyright 2002-2006 Loyola University Chicago,
 * Department of Computer Science and the Emerging Technologies Laboratory.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License via
 *    http://www.apache.org/licenses/LICENSE-2.0.
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.citep.formats.input.gnucash;

import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;

import com.citep.formats.input.accounts.AccountImportSink;
import com.citep.formats.input.accounts.ImportedAccount;
import com.citep.business.Account;
import com.citep.business.AccountTypes;

public class GNUCashAccountsXMLHandler implements ContentHandler {
	
	private AccountImportSink listener;
	private ImportedAccount currentAccount;
	private STATE state;
	private StringBuffer buf;
	
	public GNUCashAccountsXMLHandler(AccountImportSink listener) {
		this.listener = listener;
		buf = new StringBuffer();
	}
	
	public void characters(char[] ch, int start, int length) throws SAXException {
		// TODO Auto-generated method stub
		buf.append(ch, start, length);
	}

	public void endDocument() throws SAXException {
		System.out.println("End document: process now");
		if(listener != null)
			listener.onDocumentEnd();
	}

	public void endElement(String uri, String localName, String qName) throws SAXException {
		// TODO Auto-generated method stub
		
		String data = buf.toString().trim();
		
		
		if("gnc:account".equals(qName)) {
			if(listener != null) {
				listener.onImportAccount(currentAccount);
			}
			currentAccount = new ImportedAccount();
		} else if("act:id".equals(qName)) {
			currentAccount.setImportId(data);
		} else if("act:type".equals(qName)) {
			setAccountType(data);
		} else if("act:description".equals(qName)) {
			currentAccount.setDescription(data);
		} else if("act:parent".equals(qName)) {
			currentAccount.setImportParentId(data);
		} else if("act:name".equals(qName)) {
			currentAccount.setName(data);
		}
		clearBuffer();
	}
	
	private void setAccountType(String data) {
		if("ASSET".equals(data)) {
			currentAccount.setType(AccountTypes.ASSETS);
		} else if("BANK".equals(data)) {
			currentAccount.setType(AccountTypes.ASSETS);			
		} else if("CASH".equals(data)) {
			currentAccount.setType(AccountTypes.ASSETS);			
		} else if("ASSET".equals(data)) {
			currentAccount.setType(AccountTypes.ASSETS);			
		} else if("CREDIT".equals(data)) {
			currentAccount.setType(AccountTypes.LIABILITY);			
		} else if("LIABILITY".equals(data)) {
			currentAccount.setType(AccountTypes.LIABILITY);
		} else if("PAYABLE".equals(data)) {
			currentAccount.setType(AccountTypes.LIABILITY);			
		} else if("RECEIVABLE".equals(data)) {
			currentAccount.setType(AccountTypes.ASSETS);			
		} else if("STOCK".equals(data)) {
			currentAccount.setType(AccountTypes.ASSETS);			
		} else if("MUTUAL".equals(data)) {
			currentAccount.setType(AccountTypes.ASSETS);			
		} else if("INCOME".equals(data)) {
			currentAccount.setType(AccountTypes.INCOME);
		} else if("EXPENSE".equals(data)) {
			currentAccount.setType(AccountTypes.EXPENSES);		
		} else if("EQUITY".equals(data)) {
			currentAccount.setType(AccountTypes.EQUITY);		
		} else if("CURRENCY".equals(data)) {
			currentAccount.setType(AccountTypes.ASSETS);		
		}
	}
	
	private void clearBuffer() {
		//clear out the buffer so we can receive new data for the next element
		buf.delete(0, buf.length());
	}

	public void endPrefixMapping(String prefix) throws SAXException {
		// TODO Auto-generated method stub
		
	}

	public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
		// TODO Auto-generated method stub
		
	}

	public void processingInstruction(String target, String data) throws SAXException {
		// TODO Auto-generated method stub
		
	}

	public void setDocumentLocator(Locator locator) {
		// TODO Auto-generated method stub
		
	}

	public void skippedEntity(String name) throws SAXException {
		// TODO Auto-generated method stub
		
	}

	public void startDocument() throws SAXException {
		// TODO Auto-generated method stub
		
	}

	public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
		
//		System.out.println("Start element: " + qName);
		if("gnc:account".equals(qName)) {
			currentAccount = new ImportedAccount();
		} else if("act:id".equals(qName)) {
			state = STATE.ID;
		} else if("act:type".equals(qName)) {
			state = STATE.TYPE;
		} else if("act:description".equals(qName)) {
			state = STATE.DESCRIPTION;
		} else if("act:parent".equals(qName)) {
			state = STATE.PARENT;
		}
	}

	public void startPrefixMapping(String prefix, String uri) throws SAXException {
		// TODO Auto-generated method stub
		
	}

	private enum STATE {
		ID,TYPE,DESCRIPTION,NAME,PARENT;
	}

}
